// These are meant to be typed into the REPL. You can also run
// scala -Xnojline < 15_partial.sc to run them all at once.

/**
 * 偏函数
 */

//使用偏函数解决
val list = List(1, 2, 3, 4, "hello")
//定义一个偏函数
//1. PartialFunction[Any,Int] 表示偏函数接收的参数类型是Any,返回类型是Int
//2. isDefinedAt(x: Any) 如果返回true ,就会去调用 apply 构建对象实例,如果是false,过滤
//3. apply 构造器 ,对传入的值 + 1,并返回（新的集合）
val partialFun = new PartialFunction[Any,Int] {

  override def isDefinedAt(x: Any) = {
    println("x=" + x)
    x.isInstanceOf[Int]
  }

  override def apply(v1: Any) = {
    println("v1=" + v1)
    v1.asInstanceOf[Int] + 1
  }
}

//使用偏函数
//说明：如果是使用偏函数，则不能使用map,应该使用collect
//说明一下偏函数的执行流程
//1. 遍历list所有元素
//2. 然后调用 val element = if(partialFun-isDefinedAt(list单个元素)) {partialFun-apply(list单个元素) }
//3. 每得到一个 element,放入到新的集合，最后返回
val list2 = list.collect(partialFun)
println("list2" + list2)


// 简写：
// 1)
//可以将前面的案例的偏函数简写
def partialFun2: PartialFunction[Any,Int] = {
  //简写成case 语句，不匹配的直接忽略
  case i:Int => i + 1
//  case j:Double => (j * 2).toInt
}
val list3 = List(1, 2, 3, 4, 1.2, 2.4, 1.9f, "hello")
val list4 = list3.collect(partialFun2)
println("list4=" + list4)

// 2）
//第二种简写形式
val list5 = list.collect{
  case i:Int => i + 1
  case j:Double => (j * 2).toInt
  case k:Float => (k * 3).toInt
}
println("list5=" + list5) // (2,3,4,5)


val f: PartialFunction[Char, Int] = { case '+' => 1 ; case '-' => -1 }
f('-') 
f.isDefinedAt('0')

f('0') 
